﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Linq;

namespace Gmantis.Controls.DataGrid
{
    [TemplateVisualState(Name = "Disabled", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "InvalidFocused", GroupName = "ValidationStates"), 
    TemplateVisualState(Name = "Valid", GroupName = "ValidationStates"), 
    TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates"), 
    TemplatePart(Name = "ToggleDetails", Type = typeof(ToggleButton)), 
    TemplateVisualState(Name = "Unselected", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Selected", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Editing", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Normal", GroupName = "CommonStates"), 
    TemplatePart(Name = "Resize", Type = typeof(FrameworkElement)), 
    TemplateVisualState(Name = "InvalidUnfocused", GroupName = "ValidationStates"), 
    TemplateVisualState(Name = "Merging", GroupName = "MergingStates"), 
    TemplateVisualState(Name = "NotMerging", GroupName = "MergingStates")]
    public class DataGridRowHeaderPresenter : ContentControl, IRecyclable, INotifyPropertyChanged
    {
        // Fields
        private double _actualHeight;
        internal FrameworkElement _elementResize;
        internal ToggleButton _elementToggleDetails;
        internal bool _isLoaded;
        private DragHelper _resizeDragHelper;
        private TapHelper _resizeTapHelper;
        private TapHelper _tapHelper;
        private bool _throwIsMouseOverChanged;
        private ViewRow _viewRow;
        public static readonly DependencyProperty CanUserResizeProperty = DependencyProperty.Register("CanUserResize", typeof(bool), typeof(DataGridRowHeaderPresenter), new PropertyMetadata(true, new PropertyChangedCallback(DataGridRowHeaderPresenter.OnCanUserResizePropertyChanged)));
        public static readonly DependencyProperty CanUserToggleDetailsProperty = DependencyProperty.Register("CanUserToggleDetails", typeof(bool), typeof(DataGridRowHeaderPresenter), new PropertyMetadata(false));
        public static readonly DependencyProperty DetailsVisibilityProperty = DependencyProperty.Register("DetailsVisibility", typeof(Visibility), typeof(DataGridRowHeaderPresenter), new PropertyMetadata(Visibility.Collapsed));
        internal static readonly DependencyProperty ForceMouseOverProperty = DependencyProperty.Register("ForceMouseOver", typeof(bool), typeof(DataGridRowHeaderPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridRowHeaderPresenter.OnForceMouseOverPropertyChanged)));
        public static readonly DependencyProperty IsEditingProperty = DependencyProperty.Register("IsEditing", typeof(bool), typeof(DataGridRowHeaderPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridRowHeaderPresenter.OnIsEditingPropertyChanged)));
        public static readonly DependencyProperty IsMergingProperty = DependencyProperty.Register("IsMerging", typeof(bool), typeof(DataGridRowHeaderPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridRowHeaderPresenter.OnIsMergingPropertyChanged)));
        public static readonly DependencyProperty IsMouseOverProperty = DependencyProperty.Register("IsMouseOver", typeof(bool), typeof(DataGridRowHeaderPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridRowHeaderPresenter.OnIsMouseOverPropertyChanged)));
        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(DataGridRowHeaderPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridRowHeaderPresenter.OnIsSelectedPropertyChanged)));
        public static readonly DependencyProperty MouseOverBrushProperty = DependencyProperty.Register("MouseOverBrush", typeof(Brush), typeof(DataGridRowHeaderPresenter), null);
        public static readonly DependencyProperty PressedBrushProperty = DependencyProperty.Register("PressedBrush", typeof(Brush), typeof(DataGridRowHeaderPresenter), null);
        internal const string ResizeElementName = "Resize";
        public static readonly DependencyProperty SelectedBackgroundProperty = DependencyProperty.Register("SelectedBackground", typeof(Brush), typeof(DataGridRowHeaderPresenter), null);
        internal const string ToggleDetailsElementName = "ToggleDetails";
        public static readonly DependencyProperty ValidationBackgroundProperty = DependencyProperty.Register("ValidationBackground", typeof(Brush), typeof(DataGridRowHeaderPresenter), null);
        public static readonly DependencyProperty ValidationForegroundProperty = DependencyProperty.Register("ValidationForeground", typeof(Brush), typeof(DataGridRowHeaderPresenter), null);
        public static readonly DependencyProperty ValidationResultsProperty = DependencyProperty.Register("ValidationResults", typeof(ICollection<ValidationResult>), typeof(DataGridRowHeaderPresenter), null);
        public static readonly DependencyProperty ValidationStateProperty = DependencyProperty.Register("ValidationState", typeof(ValidationState), typeof(DataGridRowHeaderPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridRowHeaderPresenter.OnValidationStatePropertyChanged)));

        // Events
        public event EventHandler AutoSized;
        public event EventHandler<PropertyChangedEventArgs<bool>> IsMouseOverChanged;
        public event PropertyChangedEventHandler PropertyChanged;
        public event EventHandler<PropertyChangedEventArgs<double>> Resized;
        public event EventHandler<PropertyChangedEventArgs<double>> Resizing;

        // Methods
        public DataGridRowHeaderPresenter()
        {
            RoutedEventHandler handler = null;
            this._throwIsMouseOverChanged = true;
            base.DefaultStyleKey = typeof(DataGridRowHeaderPresenter);
            if (handler == null)
            {
                handler = delegate(object param0, RoutedEventArgs param1)
                {
                    this.ChangeVisualStateSelection(false);
                    this.ChangeVisualStateValidation(false);
                    this.ChangeVisualStateMerging(false);
                    this.ChangeVisualStateCommon(false);
                };
            }
            base.Loaded += handler;
            base.MouseEnter += new MouseEventHandler(this.Control_MouseEnter);
            base.MouseLeave += new MouseEventHandler(this.Control_MouseLeave);
            this.SetCustomDefaultValues();
        }

        void IRecyclable.Collect()
        {
            this.IsCollected = true;
            this.ViewRow.FinalizeRowHeaderPresenter();
        }

        object IRecyclable.GetRecyclingKey()
        {
            return this.ViewRow.GetRowHeaderPresenterRecyclingKey();
        }

        void IRecyclable.Reuse()
        {
            this.IsCollected = false;
        }

        private void Control_MouseEnter(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = true;
            }
        }

        private void Control_MouseLeave(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = false;
            }
        }

        protected void ChangeVisualStateCommon(bool useTransitions)
        {
            if (!base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "Disabled", useTransitions);
            }
            if (base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "MouseOver", useTransitions);
            }
            if ((base.IsEnabled && !this.IsMouseOver) && !this.ForceMouseOver)
            {
                VisualStateHelper.GoToState(this, "Normal", useTransitions);
            }
        }

        protected void ChangeVisualStateMerging(bool useTransitions)
        {
            if (!this.IsMerging)
            {
                VisualStateHelper.GoToState(this, "NotMerging", useTransitions);
            }
            if (this.IsMerging)
            {
                VisualStateHelper.GoToState(this, "Merging", useTransitions);
            }
        }

        protected void ChangeVisualStateSelection(bool useTransitions)
        {
            if (this.IsSelected && this.IsEditing)
            {
                VisualStateHelper.GoToState(this, "Editing", useTransitions);
            }
            if (this.IsSelected && !this.IsEditing)
            {
                VisualStateHelper.GoToState(this, "Selected", useTransitions);
            }
            if (!this.IsSelected)
            {
                VisualStateHelper.GoToState(this, "Unselected", useTransitions);
            }
        }

        protected void ChangeVisualStateValidation(bool useTransitions)
        {
            if (this.ValidationState == ValidationState.InvalidUnfocused)
            {
                VisualStateHelper.GoToState(this, "InvalidUnfocused", useTransitions);
            }
            if (this.ValidationState == ValidationState.InvalidFocused)
            {
                VisualStateHelper.GoToState(this, "InvalidFocused", useTransitions);
            }
            if (this.ValidationState == ValidationState.Valid)
            {
                VisualStateHelper.GoToState(this, "Valid", useTransitions);
            }
        }

        private T GetTemplateChild<T>(string childName, bool required, ref string errors) where T : class
        {
            DependencyObject templateChild = base.GetTemplateChild(childName);
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "template part", childName, templateChild, required, ref errors);
            return (templateChild as T);
        }

        private static Storyboard GetTemplateChildResource(FrameworkElement root, string resourceName, bool required, ref string errors)
        {
            return GetTemplateChildResource<Storyboard>(root, resourceName, required, ref errors);
        }

        private static T GetTemplateChildResource<T>(FrameworkElement root, string resourceName, bool required, ref string errors) where T : class
        {
            object child = root.Resources[resourceName];
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "resource", resourceName, child, required, ref errors);
            return (child as T);
        }

        private void InitializeResizePart()
        {
            this._resizeTapHelper = new TapHelper(this._elementResize, false);
            this._resizeTapHelper.DoubleTapped += new EventHandler<TappedEventArgs>(this.ResizeDoubleTapped);
            this._resizeDragHelper = new DragHelper(this._elementResize, DragHelperMode.TranslateXY, 1.0, true, false, false, false);
            this._resizeDragHelper.DragStarted += new EventHandler<DragStartedEventArgs>(this.OnResizeDragStarted);
            this._resizeDragHelper.DragDelta += new EventHandler<DragDeltaEventArgs>(this.OnResizeDragDelta);
            this._resizeDragHelper.DragCompleted += new EventHandler<DragCompletedEventArgs>(this.OnResizeDragCompleted);
            this.UpdateResizeVisibility();
        }

        private void InitializeToggleDetailsPart()
        {
            this._elementToggleDetails.IsThreeState = false;
            Binding binding = new Binding
            {
                Converter = new VisibilityConverter()
            };
            this._elementToggleDetails.SetBinding(UIElement.VisibilityProperty, binding.From<DataGridRowHeaderPresenter>(this, x => x.CanUserToggleDetails));
            Binding binding2 = new Binding
            {
                Mode = BindingMode.TwoWay,
                Converter = new VisibilityConverter()
            };
            this._elementToggleDetails.SetBinding(ToggleButton.IsCheckedProperty, binding2.From<DataGridRowHeaderPresenter>(this, x => x.DetailsVisibility));
            this.UpdateToggleDetails();
        }

        protected internal virtual void Load()
        {
            this._tapHelper = new TapHelper(this, false);
            this._tapHelper.Tapped += new EventHandler<TappedEventArgs>(this.OnRowHeaderTapped);
            this.Row.CanUserToggleDetailsChanged += new EventHandler<PropertyChangedEventArgs<bool>>(this.Row_CanUserToggleDetailsChanged);
            this.Row.DetailsVisibilityChanged += new EventHandler<PropertyChangedEventArgs<Visibility>>(this.Row_DetailsVisibilityChanged);
            this.UpdateToggleDetailsVisibility();
            this.UpdateToggleDetails();
            this.UpdateSelection();
            this.UpdateValidationState();
            this.UpdateEditingRow();
        }

        private void OnAfterApplyTemplate()
        {
        }

        public override void OnApplyTemplate()
        {
            this.OnBeforeApplyTemplate();
            string errors = string.Empty;
            base.OnApplyTemplate();
            this._isLoaded = true;
            this._elementResize = this.GetTemplateChild<FrameworkElement>("Resize", false, ref errors);
            if (this._elementResize != null)
            {
                this.InitializeResizePart();
            }
            this._elementToggleDetails = this.GetTemplateChild<ToggleButton>("ToggleDetails", false, ref errors);
            if (this._elementToggleDetails != null)
            {
                this.InitializeToggleDetailsPart();
            }
            if (!string.IsNullOrEmpty(errors))
            {
                this._isLoaded = false;
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to DataGridRowHeaderPresenter.\nDetails: {0}", new object[] { errors }));
                }
            }
            else
            {
                this.ChangeVisualStateSelection(false);
                this.ChangeVisualStateValidation(false);
                this.ChangeVisualStateMerging(false);
                this.ChangeVisualStateCommon(false);
                this.OnAfterApplyTemplate();
            }
        }

        private void OnBeforeApplyTemplate()
        {
            FrameworkElement child = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
            VisualStateManager.SetCustomVisualStateManager(child, new MyVisualStateManager(this));
        }

        private void OnCanUserResizeChanged(bool oldValue)
        {
            this.UpdateResizeVisibility();
        }

        private static void OnCanUserResizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridRowHeaderPresenter presenter = d as DataGridRowHeaderPresenter;
            bool oldValue = (bool)e.OldValue;
            presenter.OnCanUserResizeChanged(oldValue);
        }

        private static void OnForceMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridRowHeaderPresenter).ChangeVisualStateCommon(true);
        }

        private static void OnIsEditingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridRowHeaderPresenter).ChangeVisualStateSelection(true);
        }

        private static void OnIsMergingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridRowHeaderPresenter).ChangeVisualStateMerging(true);
        }

        private static void OnIsMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridRowHeaderPresenter sender = d as DataGridRowHeaderPresenter;
            if ((sender.IsMouseOverChanged != null) && sender._throwIsMouseOverChanged)
            {
                PropertyChangedEventArgs<bool> args = new PropertyChangedEventArgs<bool>
                {
                    OldValue = (bool)e.OldValue,
                    NewValue = (bool)e.NewValue
                };
                sender.IsMouseOverChanged(sender, args);
            }
            sender.ChangeVisualStateCommon(true);
        }

        private static void OnIsSelectedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridRowHeaderPresenter).ChangeVisualStateSelection(true);
        }

        protected override void OnMouseEnter(MouseEventArgs e)
        {
            if (this.View != null)
            {
                this.View.SetMouseOverRow(this.Row);
            }
        }

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            if (this.View != null)
            {
                this.View.ClearMouseOver();
            }
        }

        private void OnResizeDragCompleted(object sender, DragCompletedEventArgs e)
        {
            if (this.Resized != null)
            {
                double num = this._actualHeight + e.CumulativeTranslation.Y;
                PropertyChangedEventArgs<double> args = new PropertyChangedEventArgs<double>
                {
                    OldValue = base.ActualHeight,
                    NewValue = (num >= 0.0) ? num : 0.0
                };
                this.Resized(this, args);
            }
        }

        private void OnResizeDragDelta(object sender, DragDeltaEventArgs e)
        {
            if (this.Resizing != null)
            {
                double num = this._actualHeight + e.CumulativeTranslation.Y;
                PropertyChangedEventArgs<double> args = new PropertyChangedEventArgs<double>
                {
                    OldValue = base.ActualHeight,
                    NewValue = (num >= 0.0) ? num : 0.0
                };
                this.Resizing(this, args);
            }
        }

        private void OnResizeDragStarted(object sender, DragStartedEventArgs e)
        {
            this._actualHeight = base.ActualHeight;
        }

        private void OnRowHeaderTapped(object sender, TappedEventArgs e)
        {
            if (e.OriginalSource != this._elementResize)
            {
                DataGrid dataGrid = this.DataGrid;
                dataGrid.Focus();
                if (dataGrid.Model.SetCurrentRow(this.Row, false))
                {
                    dataGrid.Model.SelectionManager.Select(dataGrid.CurrentRow);
                    dataGrid.ScrollIntoView();
                    e.Handled = true;
                }
            }
        }

        private static void OnValidationStatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridRowHeaderPresenter).ChangeVisualStateValidation(true);
        }

        protected void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private void ResizeDoubleTapped(object sender, TappedEventArgs e)
        {
            if (this.AutoSized != null)
            {
                this.AutoSized(this, new EventArgs());
                e.Handled = true;
            }
        }

        private void Row_CanUserToggleDetailsChanged(object sender, PropertyChangedEventArgs<bool> e)
        {
            this.UpdateToggleDetailsVisibility();
        }

        private void Row_DetailsVisibilityChanged(object sender, PropertyChangedEventArgs<Visibility> e)
        {
            this.UpdateToggleDetails();
        }

        private void SetCustomDefaultValues()
        {
            base.IsTabStop = false;
            base.IsEnabled = true;
        }

        protected internal virtual void Unload()
        {
            this._tapHelper.Tapped -= new EventHandler<TappedEventArgs>(this.OnRowHeaderTapped);
            this.Row.CanUserToggleDetailsChanged -= new EventHandler<PropertyChangedEventArgs<bool>>(this.Row_CanUserToggleDetailsChanged);
            this.Row.DetailsVisibilityChanged -= new EventHandler<PropertyChangedEventArgs<Visibility>>(this.Row_DetailsVisibilityChanged);
        }

        public void UpdateCurrentCell()
        {
        }

        public virtual void UpdateEditingRow()
        {
            if (this.Row != null)
            {
                this.IsEditing = this.Row.IsEditing;
            }
        }

        public void UpdateMouseOver()
        {
            if (!DesignerProperties.GetIsInDesignMode(this))
            {
                this.ForceMouseOver = this.Row.IsMouseOver;
            }
        }

        private void UpdateResizeVisibility()
        {
            if (this._elementResize != null)
            {
                this._elementResize.Visibility = this.CanUserResize ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        public void UpdateSelection()
        {
            if (!DesignerProperties.GetIsInDesignMode(this))
            {
                this.IsSelected = !this.ViewRow.View.Model.SelectionManager.Selection.Mode.IsColumnSelectionMode() && this.Row.IsSelected;
            }
        }

        private void UpdateToggleDetails()
        {
            if (((this.Row != null) && !DesignerProperties.GetIsInDesignMode(this)) && (this._elementToggleDetails != null))
            {
                this._elementToggleDetails.IsChecked = new bool?(this.Row.ActualDetailsVisibility == Visibility.Visible);
            }
        }

        internal void UpdateToggleDetailsVisibility()
        {
            if (!DesignerProperties.GetIsInDesignMode(this) && (this._elementToggleDetails != null))
            {
                this._elementToggleDetails.Visibility = (((this.Row.Type == DataGridRowType.Item) && this.DataGrid.IsDetailsTogglingAllowed) && this.Row.ActualCanUserToggleDetails) ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        public void UpdateValidationState()
        {
            this.ValidationResults = (from e in this.Row.Errors select new ValidationResult(e.Message, e.ColumnNames)).ToArray<ValidationResult>();
            this.ValidationState = ((this.Row.Errors.Count > 0) && this.DataGrid.ShowValidationIndicators) ? ValidationState.InvalidUnfocused : ValidationState.Valid;
        }

        // Properties
        bool IRecyclable.IsCollected
        {
            get
            {
                return this.IsCollected;
            }
        }

        public bool CanUserResize
        {
            get
            {
                return (bool)base.GetValue(CanUserResizeProperty);
            }
            set
            {
                base.SetValue(CanUserResizeProperty, value);
            }
        }

        public bool CanUserToggleDetails
        {
            get
            {
                return (bool)base.GetValue(CanUserToggleDetailsProperty);
            }
            set
            {
                base.SetValue(CanUserToggleDetailsProperty, value);
            }
        }

        public DataGrid DataGrid
        {
            get
            {
                if (this.ViewRow != null)
                {
                    return this.ViewRow.Row.DataGrid;
                }
                return null;
            }
        }

        public Visibility DetailsVisibility
        {
            get
            {
                return (Visibility)base.GetValue(DetailsVisibilityProperty);
            }
            set
            {
                base.SetValue(DetailsVisibilityProperty, value);
            }
        }

        internal bool ForceMouseOver
        {
            get
            {
                return (bool)base.GetValue(ForceMouseOverProperty);
            }
            set
            {
                base.SetValue(ForceMouseOverProperty, value);
            }
        }

        internal bool IsCollected { get; private set; }

        public bool IsEditing
        {
            get
            {
                return (bool)base.GetValue(IsEditingProperty);
            }
            set
            {
                base.SetValue(IsEditingProperty, value);
            }
        }

        internal bool IsLoading { get; set; }

        public bool IsMerging
        {
            get
            {
                return (bool)base.GetValue(IsMergingProperty);
            }
            set
            {
                base.SetValue(IsMergingProperty, value);
            }
        }

        public bool IsMouseOver
        {
            get
            {
                return (bool)base.GetValue(IsMouseOverProperty);
            }
            internal set
            {
                base.SetValue(IsMouseOverProperty, value);
            }
        }

        public bool IsSelected
        {
            get
            {
                return (bool)base.GetValue(IsSelectedProperty);
            }
            set
            {
                base.SetValue(IsSelectedProperty, value);
            }
        }

        public Brush MouseOverBrush
        {
            get
            {
                return (Brush)base.GetValue(MouseOverBrushProperty);
            }
            set
            {
                base.SetValue(MouseOverBrushProperty, value);
            }
        }

        public Brush PressedBrush
        {
            get
            {
                return (Brush)base.GetValue(PressedBrushProperty);
            }
            set
            {
                base.SetValue(PressedBrushProperty, value);
            }
        }

        public DataGridRow Row
        {
            get
            {
                if (this.ViewRow != null)
                {
                    return this.ViewRow.Row;
                }
                return null;
            }
        }

        public Brush SelectedBackground
        {
            get
            {
                return (Brush)base.GetValue(SelectedBackgroundProperty);
            }
            set
            {
                base.SetValue(SelectedBackgroundProperty, value);
            }
        }

        public Brush ValidationBackground
        {
            get
            {
                return (Brush)base.GetValue(ValidationBackgroundProperty);
            }
            set
            {
                base.SetValue(ValidationBackgroundProperty, value);
            }
        }

        public Brush ValidationForeground
        {
            get
            {
                return (Brush)base.GetValue(ValidationForegroundProperty);
            }
            set
            {
                base.SetValue(ValidationForegroundProperty, value);
            }
        }

        public ICollection<ValidationResult> ValidationResults
        {
            get
            {
                return (ICollection<ValidationResult>)base.GetValue(ValidationResultsProperty);
            }
            set
            {
                base.SetValue(ValidationResultsProperty, value);
            }
        }

        public ValidationState ValidationState
        {
            get
            {
                return (ValidationState)base.GetValue(ValidationStateProperty);
            }
            set
            {
                base.SetValue(ValidationStateProperty, value);
            }
        }

        internal DataGridView View
        {
            get
            {
                if (this.ViewRow == null)
                {
                    return null;
                }
                return this.ViewRow.View;
            }
        }

        internal ViewRow ViewRow
        {
            get
            {
                return this._viewRow;
            }
            set
            {
                if (this._viewRow != value)
                {
                    this._viewRow = value;
                    this.RaisePropertyChanged("Row");
                }
            }
        }

        // Nested Types
        private class MyVisualStateManager : VisualStateManager
        {
            // Fields
            private DataGridRowHeaderPresenter _rowHeaderPresenter;

            // Methods
            public MyVisualStateManager(DataGridRowHeaderPresenter rowHeaderPresenter)
            {
                this._rowHeaderPresenter = rowHeaderPresenter;
            }

            protected override bool GoToStateCore(Control control, FrameworkElement templateRoot, string stateName, VisualStateGroup group, VisualState state, bool useTransitions)
            {
                if ((((stateName != "Valid") || (this._rowHeaderPresenter == null)) || (this._rowHeaderPresenter.ValidationState == ValidationState.Valid)) && (group != null))
                {
                    return base.GoToStateCore(control, templateRoot, stateName, group, state, useTransitions);
                }
                return true;
            }
        }
    }

    public class DataGridNewRowHeaderPresenter : DataGridRowHeaderPresenter
    {
        // Methods
        public DataGridNewRowHeaderPresenter()
        {
            base.DefaultStyleKey = typeof(DataGridNewRowHeaderPresenter);
        }
    }
}
